<template>
    <div class="chat">
        <!-- 最左侧tab栏 -->
        <div class="slider">
            <slider-tab  @on-tab-change="onTabChange" />
        </div>
        <!-- 中间的二项侧边栏 -->
        <div class="slider-mid">
            <!-- 最近聊天列表组件 -->
            <recent-chat-list-tab @selectContacts="selectTargetUser" v-show="tabType === 'msg' " />
            <!-- 好友信息列表/> -->
            <user-friend-tab @selectContacts="selectTargetUser" v-show="tabType === 'tongxulu' " />
        </div>
        <!-- 聊天面板 -->
        <div class="chat-main" v-loading="isLoadingMsg">
            <!-- 初始化面板，空欢迎ui界面 -->
            <div v-if="curTargetUser == null" class="init-panel">
                <i class="el-icon-s-comment icon"></i>
            </div>
            <!-- 功能面板 -->
            <div v-else class="func-panel">
                <chat-panel :targetUser="curTargetUser"/>
            </div>
        </div>
    </div>
</template>
<script lang="ts">
import {Vue,Component} from 'vue-property-decorator'
import {Loading} from 'element-ui'
import axios from 'axios'
import io from '../socket'
import SliderTab from '../components/SliderTab.vue'
import RecentChatListTab from '../components/RecentChatListTab.vue'
import ChatPanel from '../components/ChatPanel.vue'
import UserFriendTab from '../components/UserFriendTab.vue'
import {bus} from '../conf'

@Component({
    components:{
        SliderTab,ChatPanel,RecentChatListTab,UserFriendTab
    }
})
export default class Chat extends Vue  {

    $message: any
    $notify: any
    $store: any

    // 当前选择的联系人信息
    public curTargetUser:any = null

    // 是否正在加载用户聊天信息
    public isLoadingMsg:boolean = false

    // 当前的tab栏激活类型,默认消息界面
    public tabType:string = 'msg'
    
    beforeMount() {
        const token = localStorage.getItem('token')
        if(token == null){
            this.$notify.error('您未登录，请先登录!')
            this.$router.push({name: 'Login'})
            return
        }
        this.getInitData()
        io.connect(token)
        io.socket?.on('fail',(msg:string)=>{
            this.$notify.error(msg)
        })
        io.socket?.on('init',(msg:string)=>{
            this.$notify.success(msg)
        })
        io.socket?.on('onMsg', this.onReceiveMsg)

        bus.$on('resetPanel',()=>{
            this.curTargetUser = null
        })
    }

    // tab栏切换事件
    public onTabChange(item:string){
        this.tabType = item
    }

    // 获取初始化数据，用户，好友，最近聊天记录等信息
    public getInitData(){
        const loading = Loading.service({lock: true, text: '加载内容中...', fullscreen: true})
        axios.post('/api/v1/user/all')
            .then(res=>{
                if(res.data.code === 200){
                    this.$store.commit('init',res.data.data)
                }else{
                    this.$message.error(res.data.msg);
                }
                this.$nextTick(()=>{
                    loading.close()
                })
            }).catch(err=>{
                this.$message.error('获取信息失败:' + err)
                this.$nextTick(()=>{
                    loading.close()
                })
            })
    }

    // 接收到消息
    private onReceiveMsg(data:string){
        // 解析json消息
        const msg = JSON.parse(data)
        // 获取最近的消息列表
        const recentMsgList:any[] = this.$store.state.recentMsgList
        // 是否在最近消息列表找到
        let isFind:boolean = false
        for(let i = 0; i < recentMsgList.length; i++){
            // 判断该条消息的通信双方是否已经处于最近消息列表，是则替换
            const recMsg = recentMsgList[i]
            if((recMsg.sendUser.email === msg.sendUser.email && recMsg.receiveUser.email === msg.receiveUser.email)||
                (recMsg.sendUser.email === msg.receiveUser.email && recMsg.receiveUser.email === msg.sendUser.email)){
                // 从列表中移除
                recentMsgList.splice(i,1)
                // 将新记录添加到数组的顶端
                recentMsgList.unshift(msg)
                isFind = true;
                break
            }
        }
        // 未找到则直接添加到数组的顶端
        if(!isFind){
            recentMsgList.unshift(msg)
        }
        // 将消息添加到好友的消息列表中
        const filterArr:any[] = this.$store.state.friends.filter((f:any) => {
           return f.user.email === msg.sendUser.email || f.user.email === msg.receiveUser.email
        })
        if(filterArr.length > 0 && typeof filterArr[0].msgList !== 'undefined'){
            filterArr[0].msgList.push(msg)
        }
    }

    // 获取与指定用户的聊天消息
    public getMsgListWithUser(email:string,cb:Function){
        this.isLoadingMsg = true
        axios.get('/api/v1/msg/with/' + email)
            .then(res=>{
                if(res.data.code === 200){
                    cb(res.data)
                }else{
                    this.$message.error(res.data.msg);
                }
                this.isLoadingMsg = false
            })
            .catch(err=>{
                this.isLoadingMsg = false
                this.$message.error('获取与对方的聊天记录失败:' + err)
            })
    }

    // 设置当前选择的联系人
    public selectTargetUser(user:any){
        // 从user信息中获取该用户对应的朋友关系信息
        const recentMsgList:any[] =  this.$store.state.recentMsgList
        const friend = this.$store.state.friends.filter((f:any) => f.user.email === user.email)[0]
        if(friend === undefined){
            this.$message.error("你们已经不是好友了!")
            const index = recentMsgList.findIndex(msg=> msg.showUser.email===user.email)
            if(index >= 0){
                recentMsgList.splice(index,1)
            }
            return;
        }
        // 判断朋友对象上是否存在消息记录信息，m没有则获取
        if(typeof friend.msgList === 'undefined'){
            // 获取与该用户的消息,并挂载到其身上
            this.getMsgListWithUser(user.email,(data:any)=>{
                this.$set(friend,'msgList',data.data)
                this.curTargetUser = friend
            })
        }else{
            this.curTargetUser = friend
        }
        
    }

    // 用户信息
    get userInfo(){
        return this.$store.state.user;
    }

}
</script>
<style lang="less" scoped>
    .chat{
        background-color: #fafafa;
        border: 1px solid #ccc;
        width: 800px;
        height: 90vh;
        margin: 5vh auto;
        border-radius: 5px;
        overflow: hidden;
        display: flex;
        justify-content: flex-start;
        align-items: flex-start;
    }
    .slider{
        width: 60px;
        height: 100%;
    }
    .slider-mid{
        width: 240px;
        height: 100%;
    }
    .chat-main{
        flex: 1;
        height: 100%;
        .init-panel{
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            .icon{
                font-size: 100px;
                color: #dddddd;
            }
        }
        .func-panel{
            height: 100%;
        }
    }
</style>